home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
163_01
/
cc12.c
< prev
next >
Wrap
Text File
|
1990-12-26
|
10KB
|
338 lines
/*
** open an include file
*/
doinclude() {
if(monitor) lout(line, stderr);
blanks(); /* skip over to name */
if(match("<")) ; /* ignore <> */
else match("\42"); /* ignore "" */
if((input2=fopen(lptr,"r"))==NULL) {
input2=EOF;
error("open failure on include file");
}
kill(); /* clear rest of line */
/* so next read will come from */
/* new file (if open) */
}
/*
** test for global declarations
*/
dodeclare(class) int class; {
if(amatch("char",4)) {
declglb(CCHAR,class);
return 1;
}
else if((amatch("int",3))|(class==EXTERNAL)|(class==STATIC)) {
declglb(CINT, class);
return 1;
}
return 0;
}
/*
** declare a static variable
*/
declglb(type, class) int type, class; {
int k, j, dim2, ndim;
char *ste; /* symbol table entry */
dim2 = 1;
ndim = 0;
while(1) {
if(match(";")) return;
if(match("*")) {
j=POINTER;
k=0;
}
else {
j=VARIABLE;
k=1;
}
if(symname(ssname, YES)==0) illname();
blanks();
if(streq(lptr, "(")) {
if(j==POINTER) error("pointer functions not allowed");
if(type==CCHAR) error("character functions not allowed");
if((class==STATIC)|(class==PUBLIC)) {
newfunc(class);
return;
}
else {
j=FUNCTION;
if(match("()") == 0) error("missing closing paren");
}
}
if(findglb(ssname)) multidef(ssname);
if(j!=FUNCTION) {
if(match("[")) {
k=needsub(); /* get size */
j=ARRAY; /* !0=array */
ndim = 1;
if(match("[")) {
dim2 = needsub();
ndim = 2;
if(dim2 == 0) {
error("need array size");
k = dim2 = 1;
} /* if dim2 */
} /* if match */
} /* if match */
} /* if j!= */
if(class!=EXTERNAL) j=initials(type>>2, j, k, class, dim2);
ste = addsym(ssname, j, type, k, &glbptr, class, dim2, ndim);
if(ste) ste[STATUS] |= DECLARED;
if(match(",")==0) {ns(); return;} /* more? */
}
}
/*
** declare local variables
*/
declloc(typ) int typ; {
int k, j, dim2, ndim;
#ifdef STGOTO
if(noloc) error("not allowed with goto");
#endif
if(declared < 0) error("must declare first in block");
while(1) {
while(1) {
if(endst()) return;
if(match("*")) j=POINTER;
else j=VARIABLE;
if(symname(ssname, YES)==0) illname();
/* no multidef check, block-locals are together */
k=BPW;
if (match("[")) {
ndim = 1;
k=needsub();
if(k) {
j=ARRAY;
if(typ == CINT) k = k << LBPW;
if(match("[")) {
dim2 = needsub();
k = k * dim2;
ndim = 2;
}
}
else {
j = POINTER;
k = BPW;
if(match("[")) {
dim2 = needsub();
while(inbyte() != ']') if(endst()) break;
ndim = 2;
}
}
}
else if(match("()")) j=FUNCTION;
else if((typ==CCHAR)&(j==VARIABLE)) k=SBPC;
declared = declared + k;
addsym(ssname, j, typ, csp - declared, &locptr, AUTOMATIC, dim2, ndim);
break;
}
if (match(",")==0) return;
}
}
/*
** inialize global objects
*/
initials(size, ident, dim, class, dim2) int size, ident, dim, class, dim2; {
int savedim, savectxt, dimsz, sflag, otemp;
savectxt = ctext;
sflag = -1;
ctext = 0; /* turn off interleaved source - problem with multi-line dcls */
litptr=0;
if(dim==0) dim = -1;
dimsz = dim * dim2;
savedim=dim;
if(class==PUBLIC) entry();
startglob();
if(match("=")) {
if(match("{")) {
while(dimsz) {
otemp = dimsz;
init(size, ident, &dimsz);
if(match(",")==0) break;
if(otemp != dimsz) sflag = 1;
}
needtoken("}");
}
else {
otemp = dimsz;
init(size, ident, &dimsz);
if (otemp != dimsz) sflag = 1;
}
}
if((savedim == -1) & (sflag == -1)) {
stowlit(0, size=BPW);
ident=POINTER;
}
dumplits(size);
dumpzero(size, dimsz);
ctext = savectxt; /* restore source code interleave mode */
return ident;
}
/*
** evaluate one initializer
*/
init(size, ident, dim) int size, ident, *dim; {
int value;
if(qstr(&value)) {
if((ident==VARIABLE)|(size!=1))
error("must assign to char pointer or array");
*dim = *dim- (litptr-value);
if(ident==POINTER) point();
}
else if(constexpr(&value)) {
if(ident==POINTER) error("cannot assign to pointer");
stowlit(value, size);
*dim = *dim-1;
}
}
/*
** get required array size
*/
needsub() {
int val;
if (match("]")) return 0; /* null size */
if (constexpr(&val) == 0) val = 1;
if (val<0) {
error("negative size illegal");
val = -val;
}
needtoken("]"); /* force single dimension */
return val; /* and return size */
}
/*
** begin a function
**
** called from "parse" and tries to make a function
** out of the following text
**
** Patched per P. L. Woods (DDJ #52)
*/
newfunc(class) int class; {
char *ptr, *source, *dest, funname[NAMESIZE];
#ifdef STGOTO
nogo = /* enable goto statements */
noloc = 0; /* enable block-local declarations */
#endif
lastst= /* no statement yet */
litptr=0; /* clear lit pool */
litlab=getlabel(); /* label next literal pool */
locptr=STARTLOC; /* clear local variables */
if(monitor) lout(line,stderr);
if(class==PUBLIC) { /* skip symname if STATIC -- already done */
if(symname(ssname, YES)==0) {
error("illegal function or declaration");
kill(); /* invalidate line */
return;
}
}
if(match("(")==0) error("no open paren");
if(ptr=findglb(ssname)) { /* already in symbol table ? */
if(ptr[IDENT]!=FUNCTION) multidef(ssname);
else if(ptr[STATUS] & DECLARED) multidef(ssname);
else ptr[STATUS] |= DECLARED;
/* earlier assumed to be a function */
}
else {
ptr = addsym(ssname, FUNCTION, CINT, FUNCTION, &glbptr, STATIC, 0, 0);
if(ptr) ptr[STATUS] |= DECLARED;
}
if(class==PUBLIC) entry(); /* gen the PUBLIC declaration */
source=ssname;
dest=funname;
while(*dest++=*source++); /* save function name (for ENDP) */
startfun(funname); /* gen PROC and BP manipulation */
locptr=STARTLOC;
argstk=0; /* init arg count */
while(match(")")==0) { /* then count args
/* any legal name bumps arg count */
if(symname(ssname, YES)) {
if(findloc(ssname)) multidef(ssname);
else {
++argstk;
ptr = addsym(ssname, 0, 0, argstk, &locptr, AUTOMATIC, 0, 0);
if(ptr) ptr[STATUS] |= DECLARED;
}
}
else {error("illegal argument name"); junk();}
blanks();
/* if not closing paren, should be comma */
if(streq(lptr,")")==0) {
if(match(",")==0) error("no comma");
}
if(endst()) break;
}
csp=0; /* preset stack pointer */
argtop=argstk;
while(argstk) {
/* now let user declare what types of things */
/* those arguments were */
if(amatch("char",4)) {doargs(CCHAR);ns();}
else if(amatch("int",3)) {doargs(CINT);ns();}
else {error("argument(s) not declared"); break;}
}
if(statement()!=STRETURN) ret();
endfun(funname); /* gen the ENDP */
if(litptr) {
startlit(); /* set to DATASEG */
printlabel(litlab);
dumplits(1); /* dump literals */
}
}
/*
** declare argument types
**
** called from "newfunc" this routine adds an entry in the
** local symbol